//
//  VipViewModel.swift
//  Chatup
//
//  Created by op on 2023/10/17.
//

import Foundation
import StoreKit
import SwiftyStoreKit
import SwiftyJSON
import FirebaseAnalytics

enum VIPProduct: String {
    case weak = "sub_weekly_3d_6.99"
    case year = "sub_yearly_0d_39.99"
}

class VipItemModel {
    var title:String = ""
    var price:String = ""
    var weekPrice:String = ""
    var productId:String = ""
    var priceValue:Double = 0

    var isFreeTrial:Bool = false
    var freeTrialDes:String = ""
    var tagIndex:Int = 0
    
    convenience init(title: String, price: String, productId: String, priceValue: Double, isFreeTrial: Bool, freeTrialDes: String, tagIndex: Int, weekPrice: String) {
        self.init()
        self.title = title
        self.price = price
        self.productId = productId
        self.priceValue = priceValue
        self.isFreeTrial = isFreeTrial
        self.freeTrialDes = freeTrialDes
        self.tagIndex = tagIndex
        self.weekPrice = weekPrice
    }
}

@MainActor
class VipViewModel:ObservableObject{
    @Published var guideItems:[SettingItemsModel] = []
    @Published var produceInfo: [VipItemModel] = []
    static let vipSharedSecret = "bbe08fbaa1d444efbf442e9a917c7ddc"
    @Published var isLoading = false
    @Published var toastStr = "Loading..."
    @Published var chooseIndex = 1
    @Published var closeVip = false
    var logFrom:String?

    init(from: String){
        logFrom = from
        guideItems.append(.init(name: String.i18nText("powered_by_gpt"), icon: "icon_vip_guide_1"))
        guideItems.append(.init(name: String.i18nText("subs_info_accurate"), icon: "icon_vip_guide_2"))
        guideItems.append(.init(name: String.i18nText("subs_info_no_limits"), icon: "icon_vip_guide_3"))
        guideItems.append(.init(name: String.i18nText("subs_info_girlfriends"), icon: "icon_vip_guide_4"))
        getData()
        
//        produceInfo.append(.init(title: "Yearly Access", price: "$24.99/year", productId: "", priceValue: 40, isFreeTrial: false, freeTrialDes: "$0.77/Week, Save 88%", tagIndex: 0))
//        produceInfo.append(.init(title: "Weekly Access", price: "$3.99/week", productId: "", priceValue: 7, isFreeTrial: true, freeTrialDes: "3 Days for Free", tagIndex: 1))
        
        logShowVip()


    }
    func getData(){
        loadProductsInfo { items in
            if items.count > 0 {
                self.produceInfo.removeAll()
                items.forEach { item in
                    if let priceYear = items.first?.priceValue, let weekYear = items.last?.priceValue {
                        if item.productId == VIPProduct.year.rawValue {
                            self.produceInfo.append(.init(title: String.i18nText("subs_yearly"), price:String.i18nText("subs_price_yearly", item.price), productId: item.productId, priceValue: item.priceValue, isFreeTrial: false, freeTrialDes: String.i18nText("subs_price_save", String(Int(((weekYear * 52 - priceYear) / (weekYear * 52)) * 100.0))+"%"), tagIndex: 0,weekPrice: String.i18nText("subs_price_weekly", item.weekPrice)))
                        } else {
                            self.produceInfo.append(.init(title: String.i18nText("subs_weekly"), price: String.i18nText("subs_price_weekly", item.price), productId: item.productId, priceValue: item.priceValue, isFreeTrial: true, freeTrialDes: String.i18nText("subs_price_free_trial"), tagIndex: 1,weekPrice: item.weekPrice))
                        }
                    }
                    
                }
            }
        } onFailed: { error in
            
        }
    }
    
    
    //"sub_weekly_3d_6.99","sub_yearly_0d_39.99"
    func startPay() {
        let productId = self.chooseIndex == 0 ? VIPProduct.year.rawValue : VIPProduct.weak.rawValue
        purchaseProduct(productIDs: productId) { isSuccess in
            if isSuccess {
                DispatchQueue.main.async {
                    NotificationCenter.default.post(name: Notification.Name("refreshVip"), object: nil)
                }
            }
        }
    }
    
    func termClick(){
        UIApplication.openWebUrl(urlStr:"https://aichattings.com/terms-of-use/")
    }
    
    func privacyClick(){
        UIApplication.openWebUrl(urlStr:"https://aichattings.com/privacy-policy/")
    }
    
    func restoreClick(){
        restoreProduct()
    }
}

extension VipViewModel {
    func loadProductsInfo(onSuccessed: (([VipItemModel]) -> Void)?, onFailed: ((String) -> Void)?) {
//        self.isLoading = true
//        self.toastStr = "Loading"
        SwiftyStoreKit.retrieveProductsInfo([VIPProduct.weak.rawValue,VIPProduct.year.rawValue]) {result in
            var arr:[VipItemModel] = []
            if result.retrievedProducts.count > 1 {
//                self.isLoading = false
                print("app 内购获取列表成功")
                for product in result.retrievedProducts {
                    let info = VipItemModel()
                    info.productId = product.productIdentifier
//                    info.price = product.localizedDescription
                    
                    let formatter = NumberFormatter()
                    formatter.locale = product.priceLocale
                    formatter.numberStyle = .currency
                    info.price = formatter.string(from: product.price) ?? ""
                    
                    info.title = product.localizedTitle
                    info.priceValue = Double(truncating: product.price)
                    
                    if info.productId == VIPProduct.weak.rawValue { // weekly
                        info.isFreeTrial = true
                        info.freeTrialDes = "7 Days For Free"
                        info.weekPrice = formatter.string(from: product.price) ?? ""
                        info.tagIndex = 1
                        if info.title.count <= 0 {
                            info.title = "Weekly"
                        }
                    }else { // year
                        info.weekPrice = formatter.string(from: info.priceValue / 52 as NSNumber) ?? ""
                        info.tagIndex = 0
                        if info.title.count <= 0 {
                            info.title = "Year"
                        }
                    }
                    
                    arr.append(info)
                }
                arr = arr.sorted(by: { item1, item2 in
                    return item1.tagIndex < item2.tagIndex
                })
                self.produceInfo = arr
                onSuccessed?(arr)
                
            }else{
//                self.isLoading = true
//                self.toastStr = "load failed"
                let errStr = String(describing: result.error?.localizedDescription)
                print("app 内购获取列表失败 = \(errStr)")
                onFailed?(errStr)
            }
            
        }
    }
    
    
    func purchaseProduct(productIDs:String,complete:@escaping (Bool)->Void){
        if UserDefaults.standard.bool(forKey: "kWhetherVip") {
            return
        }
        
        logClickSub()
        
        self.isLoading = true
        self.toastStr = String.i18nText("subs_pruchasing")
        DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
            self.logShowLoading()
        }
        SwiftyStoreKit.purchaseProduct(productIDs, quantity: 1, atomically: true) {[weak self] result in
            self?.isLoading = false
            switch result {
            case .success(let purchase):
                print("Purchase Success: \(purchase.productId)")
                self?.isLoading = true
                self?.toastStr = String.i18nText("subs_pruchased")
                self?.verifyReceipt(service: .production, isRestor: false, product_id: purchase.productId)
                complete(true)
            case .error(let error):
                self?.logSubFailed()
                complete(false)
                if error.code != .paymentCancelled {
//                    self?.showErrorToast(str: "Purchase failed, try again later")
                }
                print("Purchase Faile: \(error.code)")
                switch error.code {
                case .unknown:
                    print("Unknown error. Please contact support")
                case .clientInvalid:
                    print("Not allowed to make the payment")
                case .paymentCancelled: break
                case .paymentInvalid:
                    print("The purchase identifier was invalid")
                case .paymentNotAllowed:
                    print("The device is not allowed to make the payment")
                case .storeProductNotAvailable:
                    print("The product is not available in the current storefront")
                case .cloudServicePermissionDenied:
                    print("Access to cloud service information is not allowed")
                case .cloudServiceNetworkConnectionFailed:
                    print("Could not connect to the network")
                case .cloudServiceRevoked:
                    print("User has revoked permission to use this cloud service")
                case .privacyAcknowledgementRequired: break
                case .unauthorizedRequestData:break
                case .invalidOfferIdentifier:break
                case .invalidSignature:break
                case .missingOfferParams:break
                case .invalidOfferPrice:break
                case .overlayCancelled:break
                case .overlayInvalidConfiguration:break
                case .overlayTimeout:break
                case .ineligibleForOffer:break
                case .unsupportedPlatform:break
                case .overlayPresentedInBackgroundScene:break
                    
                @unknown default:break
                }
            }
        }
    }
    
    func restoreProduct(){
        self.isLoading = true
        self.toastStr = String.i18nText("subs_verifying")
        SwiftyStoreKit.restorePurchases(atomically: true, applicationUsername: "") { result in
            if result.restoreFailedPurchases.count > 0 {
                self.isLoading = false
                //恢复失败
//                self.showErrorToast(str: "restore Failed:\(result.restoredPurchases)")
                print()
            }else if result.restoredPurchases.count > 0 {
//                self.showSuccessToast(str: "restore Success!")
                self.verifyReceipt(service: .production, isRestor: true, product_id: "")
            }else{
                self.isLoading = false
//                self.showErrorToast(str: "Nothing to Restore~")
            }
        }
    }
    
    func verifyReceipt(service:AppleReceiptValidator.VerifyReceiptURLType,isRestor:Bool,product_id:String){
        self.isLoading = true
        self.toastStr = String.i18nText("subs_verifying")
        let receipt = AppleReceiptValidator(service: service, sharedSecret: VipViewModel.vipSharedSecret)
        SwiftyStoreKit.verifyReceipt(using: receipt) {[weak self] result in
            
            switch result {
            case .success(let receipt):
                self?.logSubSuccess()
                self?.isLoading = false
                self?.closeVip = true
                let json = JSON(receipt)
                let status = json["status"].intValue

                if status == 0{
                    print("订单验证成功receipt = \(receipt)")
                    print("-----1111111-----")
                    self?.updataInfo()
                    //验证是否过期
//                    DispatchQueue.main.async {
                        let in_apps = json["latest_receipt_info"].arrayValue
                        for appJson in in_apps {
                            let expiresTime = appJson["expires_date_ms"].int64Value
                            
                            let productId = appJson["product_id"].stringValue
                            let current = Int(Date().timeIntervalSince1970 * 1000)
                            print("expiresTime:\(expiresTime)")
                            print("currentTime:\(current)")
                            if expiresTime > current {
                                print("订单验证OK，过期时间：\(expiresTime),当前时间：\(current)")
                                UserDefaults.standard.setValue(true, forKey: "kWhetherVip")
                                UserDefaults.standard.setValue(expiresTime, forKey: "kVipExpireData")
                                UserDefaults.standard.setValue(productId, forKey: "kVipProductId")
                                UserDefaults.standard.synchronize()
                                DispatchQueue.main.async {
                                    NotificationCenter.default.post(name: Notification.Name("refreshVip"), object: nil)
                                }
                                print("-----12121212-----")
                                return
                            }else{
                                // purchase  success do something
                                print("-----13131313-----")
                            }
                        }
//                    }
                }else if status == 21007 {
                    print("订单验证是沙盒模式-继续验证")
                    print("-----2222222-----")
                    self?.verifyReceipt(service: .sandbox, isRestor: isRestor, product_id: product_id)
                }else if status == 21006{
//                    self?.showErrorToast(str: "Purchase failed, try again later")
                    print("收据是有效的，但订阅服务已经过期")
                    print("-----3333333-----")
                }else if status == 21003{
//                    self?.showErrorToast(str: "Purchase failed, try again later")
                    print("receipt无法通过验证")
                    print("-----4444444-----")
                }
                
                
            case .error(let error):
                self?.logSubFailed()
                self?.isLoading = true
                self?.toastStr = "Verify Failed"
                print("订单验证失败：\(error.localizedDescription)")
                print("-----5555555-----")
            }
        }
    }
    
    func updataInfo(){
        RequestManager().postWithJson("https://backend.aichattings.com/api/v2/user/updateSubscribe", parameters: ["ep_user_id":UserDefaults.standard.string(forKey: "ep_user_id") ?? "1",
                                                                                                                 "type":"1",]) { result in
            
            switch result {
            case .success(let success):
                print("成功")
            case .failure(let failure):
                print("失败")
            }
        }
    }
    
}

class AppVipManager {
    static let shared = AppVipManager()
    
    func checkVip(){
        let product_id = UserDefaults.standard.string(forKey: "kVipProductId")
        guard let product_id = product_id else {return}
        verifyReceipt(service: .production, product_id: product_id)
    }
    private func verifyReceipt(service:AppleReceiptValidator.VerifyReceiptURLType, product_id:String){
    
        let receipt = AppleReceiptValidator(service: service, sharedSecret: VipViewModel.vipSharedSecret)
        SwiftyStoreKit.verifyReceipt(using: receipt) {[weak self] result in
            var isVip = false
            
            switch result {
            case .success(let receipt):
                let json = JSON(receipt)
                let status = json["status"].intValue

                if status == 0{
                    print("订单验证成功receipt = \(receipt)")
                    
                    print("-----666666-----")
                    //验证是否过期
                    DispatchQueue.main.async {
                        let in_apps = json["latest_receipt_info"].arrayValue
                        for appJson in in_apps {
                            var expiresTime = appJson["expires_date_ms"].int64Value
                            let productId = appJson["product_id"].stringValue
                            let current = Int64(Date().timeIntervalSince1970 * 1000)
                            
                            if service == .sandbox {
                                expiresTime = expiresTime + 60 * 30 * 1000
                            }
                            
                            if expiresTime > current {
                                print("订单验证OK，过期时间：\(Date(timeIntervalSince1970: TimeInterval(expiresTime/1000))),当前时间：\(Date(timeIntervalSince1970: TimeInterval(current/1000)))")
                                
                                UserDefaults.standard.setValue(true, forKey: "kWhetherVip")
                                UserDefaults.standard.setValue(expiresTime, forKey: "kVipExpireData")
                                UserDefaults.standard.setValue(productId, forKey: "kVipProductId")
                                UserDefaults.standard.synchronize()
                                isVip = true
                                DispatchQueue.main.async {
                                    NotificationCenter.default.post(name: Notification.Name("refreshVip"), object: nil)
                                }
                            }
                        }
                        
                        if !isVip {
                            print("所有订单全部过期！")
                            UserDefaults.standard.setValue(false, forKey: "kWhetherVip")
                            UserDefaults.standard.setValue(0, forKey: "kVipExpireData")
                            UserDefaults.standard.setValue("none", forKey: "kVipProductId")
                            UserDefaults.standard.synchronize()
                            DispatchQueue.main.async {
                                NotificationCenter.default.post(name: Notification.Name("refreshVip"), object: nil)
                            }
                        }
                    }
                }else if status == 21007 {
                    print("订单验证是沙盒模式-继续验证")
                    print("-----777777-----")
                    self?.verifyReceipt(service: .sandbox, product_id: product_id)
                }else {
                    if status == 21006{
                        print("收据是有效的，但订阅服务已经过期")
                        
                        print("-----888888-----")
                        UserDefaults.standard.setValue(false, forKey: "kWhetherVip")
                        UserDefaults.standard.setValue(0, forKey: "kVipExpireData")
                        UserDefaults.standard.setValue("none", forKey: "kVipProductId")
                        UserDefaults.standard.synchronize()
                        DispatchQueue.main.async {
                            NotificationCenter.default.post(name: Notification.Name("refreshVip"), object: nil)
                        }
                        
                    }else if status == 21003{
                        print("receipt无法通过验证")
                        print("-----999999-----")
                    }
                }
                
                
            case .error(let error):
                print("订单验证失败：\(error.localizedDescription)")
                print("-----101010-----")
            }
        }
    }
}


extension VipViewModel {
    func logShowVip(){
        Analytics.logEvent("subs_page_show", parameters: ["from":logFrom ?? ""])
    }
    
    func logClickSub(){
        Analytics.logEvent("subs_page_subscribe", parameters: ["from":logFrom ?? ""])
    }
    
    func logSwitchPage() {
        Analytics.logEvent("subs_page_switch", parameters: ["from":logFrom ?? ""])
    }
    
    func logShowLoading(){
        Analytics.logEvent("sub_page_subscribing", parameters: ["from":logFrom ?? ""])
    }
    
    func logSubSuccess(){
        Analytics.logEvent("subs_succeed", parameters: ["from":logFrom ?? ""])
    }
    
    func logSubFailed(){
        Analytics.logEvent("subs_failed", parameters: ["from":logFrom ?? ""])
    }
}
